RTSS DLLs and RTDLLs

This topic provides:

For instructions on creating DLLs, see Creating Dynamic Link Libraries.

About RTSS DLLs and RTDLLs

There are two types of real-time DLLs (RTSS DLL and RTDLL) that you can use to share code between processes or make runtime determinations of what libraries need to be loaded for a given hardware configuration.

RTSS DLLs

An RTSS DLL is not an actual DLL but an RTSS process that exports functions for use by other RTSS processes. It shares a common address space with RTSS processes. An RTSS DLL can be loaded either automatically (at boot time) or through a call to Windows from within a C/C++ program (e.g., System("RTSSrun LibName.rtss"). Although similar to RTSS applications, the entry point is Main, and the RTSS DLL is compiled and linked to generate a library of exported functions that can be linked with RTSS applications. Typically, Main for an RTSS DLL will simply issue a SuspendThread call.

The three primary differences between RTSS DLLs and implicitly loaded Win32 DLLs are:

  1. RTSS DLLs must be explicitly loaded and unloaded by the developer.
  2. There are no per-process global variables within an RTSS DLL. Since RTSS DLLs are full RTSS processes, all global variables in an RTSS DLL belong solely to the RTSS DLL process.
  3. Main is used as an entry point, not DllMain. Also, RTSS DLL Main only gets called when the RTSS DLL is initially loaded. Any per-process or per-thread initialization must be accomplished through an additional function explicitly exported from the RTSS DLL, and explicitly invoked within the calling RTSS process.

RTDLLs

RTDLLs are RTSS objects that can be dynamically loaded and unloaded using the LoadLibrary and FreeLibrary calls. An RTDLL is automatically unloaded from memory when the last RTSS process referencing it terminates. RTDLLs are supported only within the RTX environment. They cannot be called from a Win32 application.

RTDLLs should not be statically loaded or delay loaded. Because RTDLLs do not require linking to an explicit export library, they provide a convenient, flexible runtime method of changing RTDLLs or applications. However, with RTDLLs the address of each exported function used by a calling process must be explicitly obtained through a call to GetProcAddress. Additionally, because RTDLLs are not RTX processes, it is not reliable to use C runtime functions within an RTDLL loaded by more than one RTX process simultaneously. For further details about the relationship between C runtime libraries and RTDLLs see C Runtime Libraries:Programming Considerations for DLLs below.

RTDLLs differ from Win32 explicitly loaded DLLs in two significant ways:

  1. RTDLLs do not have per-process global data.
  2. DllMain is called when the last attached process frees the DLL, not once as each attached process frees the library, as is the case for Win32.

The choice of RTSS DLLs or RTDLLs for a particular application depends on the specific functional requirements of the application. The variation of hardware runtime configurations that an application must accommodate may also affect your choice.

NOTE:  RTDLLs require a valid license to be built and run. If a valid license does not exist, the RTDLL will be considered an Evaluation, and can only be run on Evaluation runtimes. You license an RTDLL by stamping it with the StampTool utility.

C Runtime Libraries: Programming Considerations for DLLs

This section discusses considerations that you should keep in mind when designing an RTSS DLL or RTDLL that will be linked with the RTX-supplied C runtime libraries, RTXlibc.lib or RTXlibcmt.lib (see C Runtime Library-Support API Overview).

The Microsoft C runtime initialization code assumes that global variables have process scope, i.e., a separate copy of all C runtime global variables and structures exist for each process using the libraries. This is not true for RTSS DLLs or RTDLLs.

RTSS DLLs

Because RTSS DLLs are RTSS processes which have been linked to generate an export library, and because they never get unloaded from memory except at termination of the RTSS process, global structures created at initialization will persist during the entire life of any process depending on the RTSS DLL.

NOTE:  A few C runtime routines are unsafe within an RTSS DLL used by multiple processes.

The routines that you should not use are: fprintf(), getenv(), perror(), printf(), vsprintf(), and wprintf(). Because these routines rely on per-process global variables, they can yield undefined behavior that may require system reboot. Note that in this context "used by multiple processes" means used by more than one process at any time between system startup and shutdown, including the same RTSS image, running twice in succession with the same RTSS PID.

RTDLLs

RTDLLs are not RTSS processes; they are RTSS objects which can be dynamically loaded and unloaded. Because other objects created by an RTDLL are always owned by the calling process, they are destroyed when that process terminates. Among other things, the C runtime initialization creates heaps used for memory allocation. These heaps persist only until the process that initially loaded the RTDLL terminates. Since the behavior of C runtime functions is reliable only in an RTDLL loaded by multiple processes given strict limitations on the LoadLibrary, FreeLibrary sequence, it is recommended that you never register RTDLLs linked with the C runtime libraries with the /s switch of RTSSrun.

RTSS DLL and RTDLL Code Examples

See RTSS DLL Code Example and RTDLL Code Example in the RTX Example Reference.

 

See Also

IntervalZero.com | Support | Give Feedback